#include "nvds_element.h"
#include <stdexcept>
#include <sstream>

#define CHECK_GST_ELEMENT(element)                                      \
    do {                                                                \
        if (!element) {                                                 \
            std::ostringstream oss_err;                                 \
            oss_err << "Gstreamer element " << #element << " is null!"; \
            throw std::runtime_error(oss_err.str());                    \
        }                                                               \
    } while (0)

NVDSElement::NVDSElement(const char *factoryname, const char *name)
{
    CHECK_GST_ELEMENT((m_element = gst_element_factory_make(factoryname, name)));
}

NVDSElement::~NVDSElement()
{
}

void NVDSElement::addSrcProbe(GstPadProbeCallback callback, void *args)
{
    if (!callback)
        return;

    GstPad *src_pad = gst_element_get_static_pad(m_element, "src");
    if (!src_pad) {
        const char *name = gst_element_get_name(m_element);
        throw std::runtime_error(std::string(name) + " gst_element_get_static_pad failed!");
    }
    gst_pad_add_probe(src_pad, GST_PAD_PROBE_TYPE_BUFFER, callback, args, NULL);
    gst_object_unref(src_pad);
}

void NVDSElement::addSinkProbe(GstPadProbeCallback callback, void *args)
{
    GstPad *sink_pad = gst_element_get_static_pad(m_element, "sink");
    if (!sink_pad) {
        const char *name = gst_element_get_name(m_element);
        throw std::runtime_error(std::string(name) + " gst_element_get_static_pad failed!");
    }
    gst_pad_add_probe(sink_pad, GST_PAD_PROBE_TYPE_BUFFER, callback, args, NULL);
    gst_object_unref(sink_pad);
}
